package com.smartwebx.ha.biz.rainwater.real.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.smartwebx.ha.biz.rainwater.real.ProcessDataManager;
import com.smartwebx.ha.biz.rainwater.real.RsvrfsrManager;
import com.smartwebx.ha.dal.realtime.dao.ProcessDataMapper;
import com.smartwebx.ha.dal.realtime.dao.handler.ProcessDataEnum;
import com.smartwebx.ha.dal.usebean.DateValue;
import com.smartwebx.ha.dal.usebean.SplitDateAndTimePointBean;
import com.smartwebx.ha.dal.usebean.SplitDatePointBean;
import com.smartwebx.ha.dal.usebean.abstr.AbstractValue;
import com.smartwebx.ha.dal.util.DateValueHandler;
import com.smartwebx.ha.dal.util.SplitDateAndTimePoint;
import com.smartwebx.ha.dal.util.SplitDatePoint;

@Service
public class ProcessDataManagerImpl implements ProcessDataManager {

	@Autowired
	private ProcessDataMapper processDataDao;

	@Autowired
	private RsvrfsrManager rsvrfsrManager;

	@Override
	public Iterable<DateValue> getWaterProcessMaxMinAvg(Date startDate,
			Date endDate, ProcessDataEnum tabName, String stcd) {
		SplitDatePointBean splitDatePointBean = SplitDatePoint.splitDatePoint(
				startDate, endDate);
		List<DateValue> processList = processDataDao.getProcessList(
				splitDatePointBean, tabName, stcd, ProcessDataEnum.WATER);
		
		if (processList.isEmpty()) {
			DateValue defDv = DateValue.getDefDv();
			return Lists.newArrayList(defDv, defDv, defDv);
		}
		
		Ordering<AbstractValue> byValueOrder = DateValueHandler.byValueOrder();
		DateValue maxDv = byValueOrder.max(processList);
		DateValue minDv = byValueOrder.min(processList);
		Iterable<Double> valIter = Iterables.transform(processList,
				DateValueHandler.paserValFun());
		Double avgVal = DateValueHandler.avg(valIter);

		DateValue avgDv = new DateValue();
		avgDv.setVal(avgVal);
		avgDv.setTm(Iterables.getLast(processList).getTm());

		return Lists.newArrayList(maxDv, minDv, avgDv);
	}

	@Override
	public Iterable<DateValue> getFlowProcessMaxMinAvg(Date startDate,
			Date endDate, ProcessDataEnum tabName, String stcd) {
		SplitDatePointBean splitDatePointBean = SplitDatePoint.splitDatePoint(
				startDate, endDate);
		List<DateValue> processList = processDataDao.getProcessList(
				splitDatePointBean, tabName, stcd, ProcessDataEnum.FLOW);
		if (processList.isEmpty()) {
			DateValue defDv = DateValue.getDefDv();
			return Lists.newArrayList(defDv, defDv, defDv);
		}

		long startTimes = startDate.getTime();
		long endTimes = endDate.getTime();
		long deffDays = (endTimes - startTimes) / (24 * 60 * 60 * 1000);

		Ordering<AbstractValue> byValOrdering = DateValueHandler.byValueOrder();
		DateValue maxDv = byValOrdering.max(processList);
		DateValue minDv = byValOrdering.min(processList);
		Iterable<Double> allVals = Iterables.transform(processList,
				DateValueHandler.paserValFun());
		Double avgVal = DateValueHandler.avg(allVals, deffDays);
		DateValue avgDv = new DateValue();
		avgDv.setVal(avgVal);
		avgDv.setTm(Iterables.getLast(processList).getTm());

		return Lists.newArrayList(maxDv, minDv, avgDv);
	}

	@Override
	public Integer getWaterExceedWarnDays(Date startDate, Date endDate,
			ProcessDataEnum tabName, String stcd, Double warn) {
		return processDataDao.getWaterExceedWarnDays(startDate, endDate,
				tabName, stcd, warn);
	}

	@Override
	public Integer getReservoirExceedWarnDays(Date startDate, Date endDate,
			String stcd) {
		List<DateValue> floodProcess = rsvrfsrManager.getSingleFloodProcess(
				startDate, endDate, stcd);
		List<MyTemp> dss = Lists.newArrayList();
		MyTemp temp = null;
		for (DateValue flood : floodProcess) {
			if (temp == null) {
				temp = new MyTemp();
				temp.setBTm(flood.getTm());
				temp.setWarnVal(flood.getVal());
				dss.add(temp);
			} else {
				if (temp.getWarnVal() != flood.getVal()) {
					temp = new MyTemp();
					temp.setBTm(flood.getTm());
					temp.setWarnVal(flood.getVal());
					dss.add(temp);
				}
			}
			temp.setETm(flood.getTm());
		}
		int sum = 0;

		for (MyTemp myTemp : dss) {
			if (myTemp.getWarnVal() != 0d) {
				Integer val = this.getWaterExceedWarnDays(myTemp.getBTm(),
						myTemp.getETm(), ProcessDataEnum.SHUI_KU, stcd,
						myTemp.getWarnVal());
				sum += val;
			}
		}

		return sum;
	}

	private class MyTemp {
		private Date bTm;
		private Date eTm;
		private Double warnVal;

		public Date getBTm() {
			return bTm;
		}

		public void setBTm(Date bTm) {
			this.bTm = bTm;
		}

		public Date getETm() {
			return eTm;
		}

		public void setETm(Date eTm) {
			this.eTm = eTm;
		}

		public Double getWarnVal() {
			return warnVal;
		}

		public void setWarnVal(Double warnVal) {
			this.warnVal = warnVal;
		}
	}

}
